/**
 * @file dynArray.h
 * @brief Si definisce una struttura e le funzioni per l'utilizzo di un'array dinamico.
 *
 * L'array gestisce elementi della stessa dimensione copiandone il valore all'interno del proprio buffer al
 * momento dell'inserimento @see DynArray_add().
 * Per elementi complessi si può specificare una funzione per la rimozione, in particolare l'attributo
 * destroy della struttura @see DynArray.
 *
 * @date Mar 16, 2012
 * @author Francesco Corvino
 */

#ifndef DYNARRAY_H_
#define DYNARRAY_H_

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/**
 * @brief permette di scorrere gli elementi dell'array.
 *
 * @param arr puntatore a un oggetto DynArray da controllare.
 * @param index puntatore a un'intero da utilizzare come indice.
 * @param tmp puntatore che conterrà l'elemento restituito.
 */
#define DYNARRAY_FOREACH(arr,index,tmp) \
		while((tmp = DynArray_getNext((arr),(index)))!=NULL)

/**
 * @brief Definisce una struttura per gli array dinamici.
 *
 * Array può essere ordinato o non a seconda se si assegna un valore
 * al puntatore a funzione <code>cmpElem</code>.
 *
 * @see DynArray_add funzione che gestisce l'aggiunta di elementi all'array.
 */
typedef struct dynArray {
	/**
	 * @brief Intero che indica i numeri di elementi presenti per l'array.
	 */
	int numelement;

	/**
	 * @brief Specifica la dimensione di ogni elemento presente nell'array.
	 */
	size_t sizeSingleElem;

	/**
	 * @brief Puntatore all'array.
	 */
	void* elemBuff;

	/**
	 * @brief Puntatore a funzione che permette l'ordinamento degli elementi.
	 */
	int (*cmpElem)(const void*,const void*);

	/**
	 * @brief Puntatore a funzione che permette la rimozione dei singoli elementi.
	 *
	 * Se non impostato la funzione destroy e remove si occupano di liberare soltato il rispettivo spazio di
	 * memoria allocato.
	 */
	void (*destroy)(const void*);
} DynArray;

void DynArray_init(DynArray * arr, int (*matchElem)(const void*, const void*), size_t sizeElem);

int DynArray_add(DynArray * arr, void * elem);

int DynArray_remove(DynArray * arr, void * elem);

void * DynArray_get(DynArray * arr, const void * index);

void * DynArray_getIndex(DynArray * arr, const int index);

void DynArray_destroy(DynArray * arr);

void * DynArray_getNext(DynArray* arr, int * index);

#endif /* DYNARRAY_H_ */
